#include "math.h" // sqrt

template< typename T, unsigned int N >
Vector<T,N>::Vector() {
  for( unsigned int i = 0; i < N; ++i ) {
    elems[i] = T();
  }
}

template< typename T, unsigned int N >
Vector<T,N>::Vector( T* vals ) {
  for( unsigned int i = 0; i < N; ++i ) {
    elems[i] = vals[i];
  }
}

template< typename T, unsigned int N >
Vector<T,N>& Vector<T,N>::operator()( T* vals ) {
  for( unsigned int i = 0; i < N; ++i ) {
    elems[i] = vals[i];
  }
}

template< typename T, unsigned int N >
template< unsigned int X > 
Vector<T,N>::Vector( const Vector<T,X>& vector ) {
  unsigned int i = 0;
  for( ; i < ((N>X)?X:N); ++i ) {
    elems[i] = vector[i];
  }
  for( ; i < N; ++i ) {
    elems[i] = T();
  }
}

template< typename T, unsigned int N >
Vector<T,N+1> Vector<T,N>::AddElem( unsigned int target, const T& val ) const {
  Vector<T,N+1> temp;
  for( unsigned int i = 0; i < target; ++i ) {
    temp[i] = elems[i];
  }
  temp[target] = val;
  for( unsigned int i = target; i < N; ++i ) {
    temp[i+1] = elems[i];
  }
  return temp;
}

template< typename T, unsigned int N >
Vector<T,N-1> Vector<T,N>::RemoveElem( unsigned int target ) const {
  Vector<T,N-1> temp;
  for( unsigned int i = 0; i < target; ++i ) {
    temp[i] = elems[i];
  }
  for( unsigned int i = target; i < N-1; ++i ) {
    temp[i] = elems[i+1];
  }
  return temp;
}

template< typename T, unsigned int N >
T Vector<T,N>::Magnitude() const {
  T magnitude = 0;
  for( unsigned int i = 0; i < N; ++i ) {
    magnitude += elems[i]*elems[i];
  }
  return sqrt(magnitude);
}

template< typename T, unsigned int N >
Vector<T,N> Vector<T,N>::Normal() const {
  Vector<T,N> temp(*this);
  return temp.Normalize();
}

template< typename T, unsigned int N >
Vector<T,N>& Vector<T,N>::Normalize() {
  T magnitude = Magnitude();
  for( unsigned int i = 0; i < N; ++i ) {
    elems[i] /= magnitude;
  }
  return *this;
}

template< typename T, unsigned int N >
bool Vector<T,N>::operator==( const Vector<T,N>& compare ) const {
  for( unsigned int i = 0; i < N; ++i ) {
    if( elems[i] != compare.elems[i] )
      return false;
  }
  return true;
}

template< typename T, unsigned int N >
bool Vector<T,N>::operator!=( const Vector<T,N>& compare ) const {
  return !( *this == compare );
}

template< typename T, unsigned int N >
bool Vector<T,N>::IsNull() const {
  for( unsigned int i = 0; i < N; ++i ) {
    if( elems[i] != T() )
      return false;
  }
  return true;
}

template< typename T, unsigned int N >
T& Vector<T,N>::operator[]( unsigned int target ) {
  return elems[target];
}

template< typename T, unsigned int N >
T  Vector<T,N>::operator[]( unsigned int target ) const {
  return elems[target];
}

template< typename T, unsigned int N >
Vector<T,N> operator-( Vector<T,N>& a) {
  Vector<T,N> temp(a);
  for( unsigned int i = 0; i < N; ++i ) {
    temp[i] = -temp[i];
  }
  return temp;
}
